<template>
	<div class="searchInput">
		<el-autocomplete
			v-model="keyword"
			:fetch-suggestions="handleSearch"
			:trigger-on-focus="false"
			clearableplaceholder="输入城市+关键字搜索"
			@select="handleSelect"
			style="width: 500px"
			clearable
		/>
	</div>
	<div ref="mapRef" class="card content-box"></div>
</template>

<script setup lang="ts">
import { ref, unref, onMounted, nextTick } from 'vue'
import { GAODE_MAP_SDK_URL } from '@/config/config'
import { useScript } from '@/hooks/useScript'
const mapRef = ref<HTMLDivElement | null>()
const { toPromise } = useScript({ src: GAODE_MAP_SDK_URL })

const emits = defineEmits(['getAdress'])

const keyword = ref()
const mapTo = ref()
let AMap = null as any
let placeSearch = ref()
let geocoder = ref()
let location = ref()

// 地图初始化
async function initMap() {
	await toPromise()
	await nextTick()
	const wrapEl = unref(mapRef)
	if (!wrapEl) return
	AMap = (window as any).AMap
	mapTo.value = new AMap.Map(wrapEl, {
		zoom: 11,
		// center: [116.397428, 39.90923],
		viewMode: '3D'
	})

	mapTo.value.on('click', onMapClick)

	AMap.plugin(['AMap.ToolBar', 'AMap.Scale', 'AMap.Geolocation', 'AMap.PlaceSearch', 'AMap.Geocoder'], () => {
		// 缩放条
		const toolbar = new AMap.ToolBar()
		// 比例尺
		const scale = new AMap.Scale()
		// 定位
		const geolocation = new AMap.Geolocation({
			enableHighAccuracy: true,
			//是否使用高精度定位，默认:
			truetimeout: 10000,
			//超过10秒后停止定位，默认：5s
			position: 'RT',
			//定位按钮的停靠位置
			buttonOffset: new AMap.Pixel(10, 20),
			//定位按钮与设置的停靠位置的偏移量，默认：Pixel(10, 20)
			zoomToAccuracy: true
			//定位成功后是否自动调整地图视野到定位点
		})
		geocoder.value = new AMap.Geocoder({ city: '全国' })
		mapTo.value.addControl(geolocation)
		mapTo.value.addControl(toolbar)
		mapTo.value.addControl(scale)
		placeSearch.value = new AMap.PlaceSearch({
			map: mapTo.value,
			city: '',
			pageSize: 30,
			// 单页显示结果条数
			pageIndex: 1,
			// 页码
			citylimit: false,
			// 是否强制限制在设置的城市内搜索
			autoFitView: true
		})
	})
}

// 输入框搜索地图位置
const handleSearch = (queryString: any, cb: any) => {
	placeSearch.value.search(queryString, (status: any, result: any) => {
		console.log('搜索', result)

		if (result && typeof result === 'object' && result.poiList) {
			const list = result.poiList.pois

			list.forEach((item: any) => {
				item.value = item.name
				item.label = item.name
			})
			cb(list)
		} else {
			cb([])
		}
	})
}

// 点击搜索项
const handleSelect = (item: any) => {
	const { pname, cityname, adname, address, name } = item
	const { lng, lat } = item.location
	let addressTo = pname + cityname + adname + address + name
	// 属性： zone: [pname, cityname, adname], name
	location.value = { longitude: lng, latitude: lat, address: addressTo }
	mapTo.value.setZoomAndCenter(16, [lng, lat])
	keyword.value = location.value.address
	emits('getAdress', location.value)
}

// 点击地图
const onMapClick = (e: any) => {
	const { lng, lat } = e.lnglat
	let val = {
		longitude: lng,
		latitude: lat
	}
	console.log('点击地图', val)
	drawMarker(val)
	getAddressFun(lng, lat)
}

// 逆地理编码
const getAddressFun = (lng: any, lat: any) => {
	geocoder.value.getAddress([lng, lat], (status: any, result: any) => {
		console.log('结果', status, result)
		if (status === 'complete' && result.info === 'OK') {
			const { addressComponent, formattedAddress } = result.regeocode
			let { city, province } = addressComponent
			if (!city) {
				// 直辖市
				city = province
			}
			// 属性： zone: [province, city, district]
			location.value = { longitude: lng, latitude: lat, address: formattedAddress }
			keyword.value = location.value.address
			emits('getAdress', location.value)
		}
	})
}

// 绘制地点marker
const marker = ref()
const drawMarker = (val: any) => {
	const { longitude, latitude } = val
	if (marker.value) {
		marker.value.setMap(null)
	}
	marker.value = new AMap.Marker({ position: new AMap.LngLat(longitude, latitude), anchor: 'bottom-center' })
	mapTo.value.add(marker.value)
	mapTo.value.setZoomAndCenter(16, [longitude, latitude])
}

onMounted(() => {
	initMap()
})
</script>
<style scoped lang="scss">
.searchInput {
	padding-bottom: 20px;
}
.content-box {
	height: 460px;
}
</style>
